package com.golxen.framework.netty.session.game;


import com.golxen.framework.PBPacket.PBPacket;
import com.golxen.framework.netty.NettyServices;
import com.golxen.framework.netty.session.base.ServerLinkedGroup;
import com.golxen.framework.user.player.GamePlayer;
import com.golxen.framework.common.server.game.cmd.GameCommandWrapper;
import com.golxen.framework.executor.ThreadPlugin;
import com.golxen.framework.user.player.GamePlayerMgr;
import com.golxen.utils.LogUtil;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.slf4j.Logger;

@ChannelHandler.Sharable
public class GameServerHandler extends SimpleChannelInboundHandler<PBPacket> {

	private static Logger logger = LogUtil.COMMON;

	private String handlerName;

	public GameServerHandler() {
		handlerName = "game";
	}

	@Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception {
		ServerLinkedGroup client = ctx.channel().attr(NettyServices.LINKED_CLIENT).get();  //map里的值指向对象指针所有不用担心每个map不一样。这个组指向管理类里的组
		if (client != null) {
			GameServerLinkedSet.removeLinkedClient(ctx);
			logger.error(toMessage(
					"close the connection to agent disconnected. session : " + ctx.channel().remoteAddress()));
		}
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {

		ServerLinkedGroup client = ctx.channel().attr(NettyServices.LINKED_CLIENT).get();
		if (client != null) {
			GameServerLinkedSet.removeLinkedClient(ctx);
			logger.error(toMessage("caught exception the connection to agent disconnected. session : "
					+ ctx.channel().remoteAddress()));
		}

		logger.debug("connection error {} group {} ", //
				ctx.channel(), //
				client == null ? "null" : client.getServerId() + "," + client.getServerIndex() + "," + client.getPort(),
				cause //
		);
		ctx.close();
	}

	@Override
	protected void channelRead0(ChannelHandlerContext ctx, PBPacket msg) throws Exception {
		long playerId = msg.getPlayerId();
		GamePlayer player = GamePlayerMgr.getOnlinePlayer(playerId);
		GameCommandWrapper cmdWrapper = new GameCommandWrapper(ctx, msg, player);
		if (player != null) {
			// 已登录玩家，加到玩家消息执行队列
			player.getCommandQueue().add(cmdWrapper);
		} else {
			logger.debug("read0 player=null {} code={}", msg.getPlayerId(), msg.getCode());
			// 未登录玩家，直接到线程池执行
			ThreadPlugin.getServerCommandExecutor().execute(cmdWrapper);
		}
	}

	private String toMessage(String msg) {
		return "[" + handlerName + "] " + msg;
	}
}
